package cn.zn.modules.controller;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.zn.framework.common.utils.FileUtils;
import cn.zn.modules.expense.entity.TpAttachmentEntity;
import cn.zn.modules.expense.entity.TpMainEntity;
import cn.zn.modules.expense.entity.TpeFundingSourceEntity;
import cn.zn.modules.expense.service.TpAttachmentService;
import cn.zn.modules.expense.service.TpMainService;
import cn.zn.modules.expense.service.TpeFundingSourceService;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.Cleanup;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


/**
 * @author zn
 * @email zhunahao@qq.com
 * @date 2019-08-30 22:42:32
 */
@RestController
@RequestMapping("appoint")
@Slf4j
@Api(tags = "预约")
public class AppointController {
    @Autowired
    private TpAttachmentService tpAttachmentService;
    @Autowired
    private TpeFundingSourceService tpeFundingSourceService;
    @Autowired
    private TpMainService tpMainService;
    @Autowired
    private FileUtils fileUtils;

    /**
     * 列表
     */
    @RequestMapping("exportBankZip")
    @ApiOperation("导出银行账号信息")
    public void exportBankZip(String appointMainIds, HttpServletResponse response) throws IOException {
        List<ExportBankInfo> exportBankInfos = Lists.newArrayList();
        List<ImgFile> imgFiles = null;
        List<BankInfo> bankInfos = null;
        List<TpAttachmentEntity> tpAttachmentEntitys = null;
        List<TpeFundingSourceEntity> tpeFundingSourceEntities = null;
        String[] appointMainIdArr = appointMainIds.split(",");
        TpMainEntity tpMain = null;
        for (String appointMainId : appointMainIdArr) {
            tpMain = tpMainService.findByAppontMainId(appointMainId);
            // 得到附件
            imgFiles = Lists.newArrayList();
            tpAttachmentEntitys = tpAttachmentService.findByAppontMainId(appointMainId);
            for (TpAttachmentEntity tpAttachment : tpAttachmentEntitys) {
                imgFiles.add(new ImgFile(tpAttachment.getRealName().concat(".").concat(tpAttachment.getSuffix()), tpAttachment.getPathLocal()));
            }
            // 得到银行信息
            tpeFundingSourceEntities = tpeFundingSourceService.findByAppontMainId(appointMainId);
            bankInfos = Lists.newArrayList();
            for (TpeFundingSourceEntity fs : tpeFundingSourceEntities) {
                bankInfos.add(new BankInfo(fs.getReceivablesName(), fs.getReceivablesAccount(), fs.getReceivablesBank(), fs.getMoney(), fs.getRemark()));
            }
            // 整理一个报销单的打包信息
            exportBankInfos.add(new ExportBankInfo(bankInfos, imgFiles, tpMain.getApplyCode()));
        }

        // 生成文件，及打包

        String zipDir = fileUtils.getSaveDir().concat(File.separator).concat("zip");
        File zipDirFile = new File(zipDir);
        if (!zipDirFile.exists()) {
            zipDirFile.mkdirs();
        }
        File zipFile = new File(zipDir.concat(File.separator).concat("bank").concat(String.valueOf(System.currentTimeMillis())).concat(".zip"));
        @Cleanup ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(zipFile));
        StringBuilder bankInfoStr = null;
        File file = null;
        for (ExportBankInfo exportBankInfo : exportBankInfos) {
            bankInfoStr = new StringBuilder();
            bankInfoStr.append("银行账户,");
            bankInfoStr.append("银行账号,");
            bankInfoStr.append("开户行,");
            bankInfoStr.append("说明,");
            bankInfoStr.append("金额,\r\n");
            for (BankInfo bankInfo : exportBankInfo.getBankInfos()) {
                bankInfoStr.append(this.formatBankNum(bankInfo.getReceivablesAccount())).append(",");
                bankInfoStr.append(StrUtil.isNotBlank(bankInfo.getReceivablesName()) ? bankInfo.getReceivablesName() : "").append(",");
                bankInfoStr.append(StrUtil.isNotBlank(bankInfo.getReceivablesBank()) ? bankInfo.getReceivablesBank() : "").append(",");
                bankInfoStr.append(StrUtil.isNotBlank(bankInfo.getRemark()) ? bankInfo.getRemark() : "").append(",");
                bankInfoStr.append(bankInfo.getMoney() != null ? bankInfo.getMoney() : "").append(",\r\n");
            }
            zip.putNextEntry(new ZipEntry(exportBankInfo.getPackageName().concat(File.separator).concat("bank.csv")));
            IoUtil.write(zip, "GBK", false, bankInfoStr);
            zip.closeEntry();
            for (ImgFile imgFile : exportBankInfo.getImgFiles()) {
                file = new File(imgFile.getFilePath());
                if (file.exists()) {
                    zip.putNextEntry(new ZipEntry(exportBankInfo.getPackageName().concat(File.separator).concat(imgFile.getFileName())));
                    IOUtils.write(this.getImageStream(file), zip);
                    zip.closeEntry();
                }
            }
        }

        /*response.reset();
        response.setHeader("Content-Disposition", "attachment; filename=\"bank.zip\"");
        response.addHeader("Content-Length", "" + data.length);
        response.setContentType("application/octet-stream; charset=UTF-8");
        IoUtil.write(response.getOutputStream(), true, data);*/
        response.sendRedirect(fileUtils.getDomainUrlForSavePath(zipFile.getPath()));
    }

    /**
     * 图片转byte
     *
     * @param imgFile
     * @return
     */
    private byte[] getImageStream(File imgFile) {
        byte[] buffer = null;
        ByteArrayOutputStream bos = null;
        FileInputStream fis = null;
        try {
            bos = new ByteArrayOutputStream();
            fis = new FileInputStream(imgFile);
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }

            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            log.error("", e);
        } catch (IOException e) {
            log.error("", e);
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
                if (bos != null) {
                    bos.close();
                }
            } catch (IOException e) {
                log.error("", e);
            }
        }
        return buffer;
    }

    /**
     * 格式化银行账号
     *
     * @param bankNum
     * @return
     */
    private String formatBankNum(String bankNum) {
        if (StrUtil.isBlank(bankNum)) {
            return "";
        }
        bankNum = bankNum.replace(" ", "");
        StringBuilder sb = new StringBuilder(bankNum);
        int length = bankNum.length() / 4 + bankNum.length();

        for (int i = 0; i < length; i++) {
            if (i % 5 == 0) {
                sb.insert(i, " ");
            }
        }
        sb.deleteCharAt(0);
        return sb.toString();
    }

    @Data
    @AllArgsConstructor
    class ExportBankInfo {
        List<BankInfo> bankInfos;
        List<ImgFile> imgFiles;
        String packageName;
    }

    @Data
    @AllArgsConstructor
    class BankInfo {
        /**
         * 收款名称
         */
        private String receivablesName;
        /**
         * 收款账号
         */
        private String receivablesAccount;
        /**
         * 开户行
         */
        private String receivablesBank;
        /**
         * 金额
         */
        private Double money;
        /**
         * 说明
         */
        private String remark;
    }

    @Data
    @AllArgsConstructor
    class ImgFile {
        String fileName;
        String filePath;
    }
}
